//
//  CoreDataManager.swift
//  CoreDataDemo
//
//  Created by MAC on 2019/3/19.
//  Copyright © 2019 zk. All rights reserved.
//

import UIKit
import CoreData


enum SignStatus {
    case success(User)
    case failure(String)
}

class CoreDataManager: NSObject {

    static let shared = CoreDataManager()
   
    lazy var managedObjectModel: NSManagedObjectModel = {
        let modelURL = Bundle.main.url(forResource: "baozha", withExtension: "momd")
        let managedObjectModel = NSManagedObjectModel.init(contentsOf: modelURL!)
        return managedObjectModel!
    }()
    
    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        let persistentStoreCoordinator = NSPersistentStoreCoordinator.init(managedObjectModel: managedObjectModel)
        let sqliteURL = documentDir.appendingPathComponent("baozha.sqlite")
        let options = [NSMigratePersistentStoresAutomaticallyOption : true, NSInferMappingModelAutomaticallyOption : true]
        var failureReason = "There was an error creating or loading the application's saved data."
        
        do {
            try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: sqliteURL, options: options)
        } catch {
            // Report any error we got.
            var dict = [String: Any]()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as Any?
            dict[NSLocalizedFailureReasonErrorKey] = failureReason as Any?
            dict[NSUnderlyingErrorKey] = error as NSError
            let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 6666, userInfo: dict)
            print("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
            abort()
        }
        return persistentStoreCoordinator
    }()
    
    lazy var documentDir: URL = {
        let documentDir = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first
        return documentDir!
    }()
    lazy var context: NSManagedObjectContext = {
        let context = NSManagedObjectContext.init(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
        context.persistentStoreCoordinator = persistentStoreCoordinator
        return context
    }()
}

extension CoreDataManager {
    
    
    func check(_ userName: String, password: String) -> SignStatus {
        let fetchRequest = NSFetchRequest<User>(entityName:"User")
        let predicate = NSPredicate(format: "userName = %@", userName)
        fetchRequest.predicate = predicate
        do {
            let fetchedObjects = try context.fetch(fetchRequest)
            if fetchedObjects.count == 0{
                return SignStatus.failure("账号不存在")
            }
            
            if fetchedObjects.first?.password ?? "" == password {
                return SignStatus.success(fetchedObjects.first!)
            }else {
                return SignStatus.failure("密码错误")
            }
        }
        catch {
            fatalError("不能查询：\(error)")
        }
    }
    
    func insertUser(userName: String, password: String ) -> SignStatus{
        
        let all = findAllUser()
        if all.count != 0 {
            for user in all {
                if user.userName! == userName {
                    return SignStatus.failure("账号已存在")
                }
            }
        }
        
        let entity = NSEntityDescription.insertNewObject(forEntityName: "User", into: context) as! User
        entity.userName = userName
        entity.password = password
        entity.userId = Int32(findAllUser().count)
        saveContext()
        return .success(entity)
    }
}

extension CoreDataManager {
    
    fileprivate func findAllUser() -> [User] {
        let fetchRequest = NSFetchRequest<User>(entityName:"User")
        
        do {
            let fetchedObjects = try context.fetch(fetchRequest)
            return fetchedObjects
        }
        catch {
            fatalError("不能查询：\(error)")
        }
    }
    
    fileprivate func saveContext() {
        do {
            try  context.save()
        } catch {
            
        }
    }
}
